﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using Ornament.MemberShip;
using Ornament.MemberShip.Permissions;
using Ornament.MVCWebFrame.Models;
using Ornament.Web;
using Ornament.Web.MemberShips;
using Ornament.Web.Mvc;

namespace Ornament.MVCWebFrame.Areas.MemberShips.Controllers
{
    /// <summary>
    /// </summary>
    [Authorize(Users = "admin")]
    public class UserController : Controller
    {
        public ActionResult Index()
        {
            IList<User> result = OrnamentContext.Current.MemberShipFactory.CreateUserDao().FindAll(0, 50);
            return View(result);
        }

        public ActionResult Edit(string id)
        {
            ViewData.Model = OrnamentContext.Current.MemberShipFactory.CreateUserDao().Get(id);
            return View();
        }
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(User user)
        {
            var dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();
            dao.SaveOrUpdate(user);
            return RedirectToAction("Index");
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="searchValue"></param>
        /// <returns></returns>
        [JsonContainerFilter,]
        public ActionResult Search(JsonContainer searchValue)
        {
            var dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();


            var result = from u in
                             dao.FindUsersByLoginId(searchValue.ToString("loginId"), searchValue.ToInt32("pageIndex"), 30)
                         select new
                                    {
                                        Name = String.IsNullOrEmpty(u.Information.Name) ?
                                              u.LoginId : String.Format("{0}({1}）", u.Name, u.LoginId),
                                        LoginId = u.LoginId
                                    };

            return Json(result, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Assign(string id)
        {
            var user = OrnamentContext.Current.MemberShipFactory.CreateUserDao().Get(id);
            var userGroupRoleMap = new Dictionary<string, List<string>>();
            var rolePermissionsMap = new Dictionary<string, List<string>>();
            foreach (var ug in OrnamentContext.Current.MemberShipFactory.CreateUserGroupDao().GetAll())
            {
                userGroupRoleMap.Add(ug.Id.ToString("N"), new List<string>());
                foreach (var role in ug.GetAllRoles())
                {
                    userGroupRoleMap[ug.Id.ToString("N")].Add(role.Id.ToString("N"));
                }

            }
            foreach (var role in OrnamentContext.Current.MemberShipFactory.CreateRoleDao().GetAll())
            {
                rolePermissionsMap.Add(role.Id.ToString("N"), new List<string>());
                foreach (var permission in role.Permissions)
                {
                    rolePermissionsMap[role.Id.ToString("N")].Add(permission.Id.ToString("N"));
                }

            }
            ViewData["userGroupRoleMap"] = userGroupRoleMap;
            ViewData["rolePermissionMap"] = rolePermissionsMap;


            return View(user);
        }
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Assign(string[] roles, Guid[] userGroups, string loginId)
        {
            var roleDao = OrnamentContext.Current.MemberShipFactory.CreateRoleDao();
            var userGroupDao = OrnamentContext.Current.MemberShipFactory.CreateUserGroupDao();
            var user = OrnamentContext.Current.MemberShipFactory.CreateUserDao().Get(loginId);
            user.ClearRole();
            bool findMember = false;
            foreach (var role in roleDao.GetRoles(roles))
            {
                findMember = role.Name == "member";
                user.AddRole(role);
            }

            foreach (var ug in userGroupDao.GetUserGroups(userGroups))
            {
                user.AddToUserGroup(ug);
            }

            if (!findMember)
                user.AddRole(roleDao.GetByName("member"));

            return RedirectToAction("Index");
        }

        public ActionResult CreateWizard()
        {
            return View();
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult CreateWizard(User user, string[] roles, Guid[] selectorUserGroups)
        {
            if (this.ModelState.IsValid)
            {
                if (roles != null && roles.Length != 0)
                {
                    var roleDao = OrnamentContext.Current.MemberShipFactory.CreateRoleDao();
                    foreach (var role in roleDao.GetRoles(roles))
                        user.AddRole(role);
                }

                if (selectorUserGroups != null && selectorUserGroups.Length != 0)
                {
                    foreach (
                        var ug in
                            OrnamentContext.Current.MemberShipFactory.CreateUserGroupDao().GetUserGroups(
                                selectorUserGroups))
                    {
                        user.AddToUserGroup(ug);
                    }
                }

                OrnamentContext.Current.MemberShipFactory.CreateUserDao().SaveOrUpdate(user);
                return RedirectToAction("index");
            }
            return View(user);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public ActionResult IsExit(string userName)
        {
            IUserDao dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();
            bool exist = dao.Get(userName) != null;
            var o = new
                        {
                            Result = exist
                        };
            return base.Json(o, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="email"></param>
        /// <returns></returns>
        public ActionResult EmailIsExist(string email)
        {
            IUserDao dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();
            return base.Json(dao.GetUserByEmail(email) != null);
        }

        [ResourceAuthorize(UserOperator.Lock, "Reader")]
        public ActionResult UnlockUser(string loginId)
        {
            IUserDao dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();
            foreach (string loginid in loginId.Split(','))
            {
                User user = dao.Get(loginid);
                user.IsLockout = false;
            }
            return Json(new ReturnResult("成功解锁以下用户" + loginId, true));
        }

        [ResourceAuthorize(UserOperator.Approve, "Reader")]
        public ActionResult Approve(string loginId)
        {
            IUserDao dao = OrnamentContext.Current.MemberShipFactory.CreateUserDao();
            foreach (string loginid in loginId.Split(','))
            {
                User user = dao.Get(loginid);
                user.IsApproved = true;
            }
            return Json(new ReturnResult("成功激活以下用户" + loginId, true));
        }

        [ResourceAuthorize(UserOperator.SetPassword, "Reader")]
        public ActionResult ResetPassword(string loginId)
        {
            var privoder = Membership.Provider as MemberShipProvider;
            User user = OrnamentContext.Current.MemberShipFactory.CreateUserDao().Get(loginId);
            string newpassword = Membership.GeneratePassword(Membership.MinRequiredPasswordLength, 0);

            user.ChangePassword(privoder.EncodeString(newpassword, privoder.PasswordFormat));

            OrnamentContext.Current.MemberShipFactory.CreateUserDao().SaveOrUpdate(user);
            return Json(newpassword);
        }
    }
}